package org.example.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;
import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;

import javax.annotation.PreDestroy;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;


@Service
//@EnableScheduling
@Slf4j
public class StudentHeartbeatService {
    private StompSession stompSession;
    private ScheduledFuture<?> heartbeatTask;
    @Autowired
    private TaskScheduler taskScheduler;

    // 教师机IP地址和端口配置
    private static final String TEACHER_IP = "192.168.103.13"; // 替换为实际教师机IP
    private static final int TEACHER_PORT = 8098; // 替换为实际教师机端口
    private static final long HEARTBEAT_INTERVAL = 5000; // 心跳间隔5秒

    public synchronized boolean connect() {
        if (stompSession != null && stompSession.isConnected()) {
            return true;
        }

        // 1. 创建传输层
        List<Transport> transports = new ArrayList<>();
        transports.add(new WebSocketTransport(new StandardWebSocketClient()));

        // 2. 创建STOMP客户端
        WebSocketStompClient stompClient = new WebSocketStompClient(new SockJsClient(transports));

        // 3. 配置客户端
        stompClient.setMessageConverter(new StringMessageConverter());
        stompClient.setTaskScheduler(this.taskScheduler); // 关键设置
        stompClient.setDefaultHeartbeat(new long[]{10000, 10000});

        String teacherWebSocketUrl = String.format("http://%s:%d/teacher-websocket", TEACHER_IP, TEACHER_PORT);

        try {
            stompSession = stompClient.connect(teacherWebSocketUrl, new StompSessionHandlerAdapter() {
                @Override
                public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
                    System.out.println("教师机连接成功");

                    // 订阅响应频道
                    session.subscribe("/topic/pong", new StompSessionHandlerAdapter() {
                        @Override
                        public Type getPayloadType(StompHeaders headers) {
                            return String.class;
                        }

                        @Override
                        public void handleFrame(StompHeaders headers, Object payload) {
                            System.out.println("收到教师机响应: " + payload);
                        }
                    });
                    startHeartbeat();
                }

                @Override
                public void handleTransportError(StompSession session, Throwable exception) {
                    System.err.println("传输错误: " + exception.getMessage());
                }
            }).get(10, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            System.err.println("连接教师机失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 断开连接并停止心跳
     */
    public synchronized void disconnect() {
        log.info("Disconnecting...");
        stopHeartbeat();

        if (stompSession != null) {
            try {
                // 延迟断开连接，确保所有消息处理完成
                Thread.sleep(1000);
                stompSession.disconnect();
                log.info("已断开与教师机的连接");
            } catch (Exception e) {
                log.error("断开连接时出错: " + e.getMessage());
            }
            stompSession = null;
        }
    }

    private void startHeartbeat() {
        if (heartbeatTask != null && !heartbeatTask.isCancelled()) {
            return;
        }

        heartbeatTask = taskScheduler.scheduleAtFixedRate(() -> {
            if (stompSession != null && stompSession.isConnected()) {
                System.out.println("向教师机发送: ping");
                stompSession.send("/app/ping", "ping");
            }
        }, HEARTBEAT_INTERVAL);
    }

    private void stopHeartbeat() {
        if (heartbeatTask != null && !heartbeatTask.isCancelled()) {
            heartbeatTask.cancel(false);
            System.out.println("心跳已停止");
        }
    }

    @PreDestroy
    public void cleanup() {
        log.info("Cleanup called, disconnecting...");
        disconnect();
    }
}